﻿using System.Collections.Generic;
using System.Linq;

namespace Tuxedo.Compile
{
	internal class ForLoop : CodeLine
	{
		private CodeLine initializer;
		private Expression condition;
		private Expression[] steps;
		private CodeLine[] loopCode;

		public ForLoop(CodeLine initializer, Expression condition, IList<Expression> steps, IList<CodeLine> loopCode)
		{
			this.initializer = initializer;
			this.condition = condition;
			this.steps = steps.ToArray();
			this.loopCode = loopCode.ToArray();
		}

		public static CodeLine Parse(TokenStream tokens)
		{
			tokens.PopExpected("for");
			tokens.PopExpected("(");
			CodeLine initializer = null;
			if (!tokens.PopIfPresent(";"))
			{
				VariableDeclaration varDecl = VariableDeclaration.Parse(tokens, true);
				if (varDecl != null)
				{
					initializer = varDecl;
				}
				else
				{
					Expression expr = Expression.ParseExpression(tokens);
					initializer = new WrappedExpression(expr); ;
					tokens.PopExpected(";");
				}
			}

			Expression condition = BooleanConstant.TRUE_INSTANCE;
			if (!tokens.IsNext(";"))
			{
				condition = Expression.ParseExpression(tokens);
			}
			tokens.PopExpected(";");

			List<Expression> steps = new List<Expression>();
			while (!tokens.PopIfPresent(")"))
			{
				if (steps.Count > 0)
				{
					tokens.PopExpected(",");
				}
				steps.Add(Expression.ParseExpression(tokens));
			}

			IList<CodeLine> loopCode = CodeLine.ParseBlock(tokens, true);

			return new ForLoop(initializer, condition, steps, loopCode);
		}
	}
}
